home *** CD-ROM | disk | FTP | other *** search
- /*
- ** L.C - A Simple Linked List manager. This file contains the functions
- ** to Create, insert, find and delete nodes in a linked list.
- ** It is for academic purposes only, and is not intended as an
- ** efficient and/or professionally useable list manager.
- **
- ** These functions have the ability to main linked lists of chars, ints,
- ** longs, and character strings. The ListNode function allows a List
- ** to be dumped to the screen. The lists are maintain in correct order,
- ** according to the data type of the list. The lists are dynamic.
- **
- ** To compile: TCC or QCL -c L.C
- **
- ** Mario Giannini
- */
- #include <stdio.h>
- #include <malloc.h> /* alloc.h for Turbo C */
- #include <string.h>
- #include "l.h"
-
- /*
- ** This array of pointers to functions is described later on
- */
- int (*Compares[4])()={IntCmp, IntCmp, LongCmp, StringCmp};
-
- Node *MakeList(int DataType) /* Starts a list in memory */
- {
- Node *P;
-
- if(!(P=calloc(sizeof(Node),1)))
- return((Node *)NULL);
- P->DataType=DataType;
- return(P);
- }
-
- int AddNode(Node *List, void *Data2Add) /* Add Node into list, in correct order */
- {
- Node *P, *Q, *S;
-
- P=List;
- if(!(S=calloc(sizeof(Node),1)))
- return(-1);
- S->DataType=List->DataType;
- switch (S->DataType) {
- case CHAR:
- S->Data.Char=*(char *)Data2Add;
- break;
- case INT:
- S->Data.Int=*(int *)Data2Add;
- break;
- case LONG:
- S->Data.Long=*(long *)Data2Add;
- break;
- case CHARSTR:
- if( (S->Data.CPntr=strdup(Data2Add))==NULL)
- {
- free(S);
- return(-1);
- }
- break;
- }
- /*
- ** This line may need some explanation. Because of the possible data types
- ** to be maintained in the list, several Compare() functions are needed. To
- ** make life easier (?) The functions that do the compare have been setup
- ** into an array of pointers to functions, each functions position in the
- ** array is equivalent to its type, so that the function Compare[INT]() will
- ** compare integers, and Compare[LONG]() would compare longs, etc.
- */
- while( P && Compares[List->DataType](P, Data2Add)<1)
- {
- Q=P;
- P=P->Next;
- }
- S->Next=P;
- S->Prev=Q;
- Q->Next=S;
- if(P)
- P->Prev=S;
- if(!S->Next)
- List->Prev=S;
- return(0);
- }
-
- /* Find Exact match in List, returns pointer to node if found, NULL if not */
- Node *FindNode(Node *P, void *Data2Find)
- {
- Node *R=P;
- while( P && Compares[R->DataType](P, Data2Find)<0)
- P=P->Next;
- if(Compares[R->DataType](P, Data2Find)==0)
- return(P);
- return(NULL);
- }
-
- DestroyList(Node *P) /* Remove an entire list from memory */
- {
- Node *Q;
-
- do {
- Q=P->Next;
- free(P);
- P=Q;
- } while(P);
- }
-
- void DeleteNode(Node *P) /* Remove a single Node from memory */
- {
- if(P->Prev)
- if(P->Next)
- P->Prev->Next=P->Next;
- else
- P->Prev->Next=NULL;
- if(P->Next)
- if(P->Prev)
- P->Next->Prev=P->Prev;
- else
- P->Next->Prev=NULL;
- if(P->DataType==CHARSTR)
- free(P->Data.CPntr);
- free(P);
- }
-
- void ListNodes(Node *P, int Dir) /* List contents of node in memory */
- {
- Node *Q=P;
-
- if(Dir)
- P=P->Prev;
- else
- P=P->Next;
- while(P && P!=Q)
- {
- if(P->DataType==INT)
- printf("%d ", P->Data);
- else
- printf(" [%s] ", P->Data);
- if(Dir)
- P=P->Prev;
- else
- P=P->Next;
- }
- }
- /*
- ** Some generic compare functions used by the functions above.
- */
-
- IntCmp(Node *N, int *D2) /* Compare integers (and chars) */
- {
- return(N->Data.Int-*D2);
- }
-
- int LongCmp(Node *N, long *D2) /* Compare longs */
- {
- return((int)(N->Data.Long-*D2));
- }
-
- int StringCmp(Node *N, char *Str) /* Compare strings */
- {
- return(stricmp(N->Data.CPntr, Str));
- }
-